package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.MallUserPropsReleasedDetailDao;
import com.sc.nft.dao.MallUserPropsRewardsDao;
import com.sc.nft.dao.MallUserPropsRewardsDetailDao;
import com.sc.nft.entity.EquityProps;
import com.sc.nft.entity.MallUserPropsReleasedDetail;
import com.sc.nft.entity.MallUserPropsRewards;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.vo.UserPropsRewardsSummaryVO;
import com.sc.nft.entity.vo.UserPropsRewardsVO;
import com.sc.nft.service.EquityPropsService;
import com.sc.nft.service.MallUserPropsRewardsService;
import com.sc.nft.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class MallUserPropsRewardsServiceImpl implements MallUserPropsRewardsService {

    private final MallUserPropsRewardsDao mallUserPropsRewardsDao;

    private final MallUserPropsRewardsDetailDao mallUserPropsRewardsDetailDao;

    private final UserInfoService userInfoService;

    private final EquityPropsService equityPropsService;

    private final MallUserPropsReleasedDetailDao mallUserPropsReleasedDetailDao;

    @Override
    public void updateByUserIdAndPropsIdAndDaoId(MallUserPropsRewards mallUserPropsRewards) {
        LambdaUpdateWrapper<MallUserPropsRewards> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(mallUserPropsRewards.getUserId() != null, MallUserPropsRewards::getUserId, mallUserPropsRewards.getUserId());
        wrapper.eq(mallUserPropsRewards.getPropsId() != null, MallUserPropsRewards::getPropsId, mallUserPropsRewards.getPropsId());
        wrapper.eq(mallUserPropsRewards.getDaoId() != null, MallUserPropsRewards::getDaoId, mallUserPropsRewards.getDaoId());
        wrapper.setSql("released_num = released_num + " + mallUserPropsRewards.getReleasedNum());
        mallUserPropsRewardsDao.update(wrapper);

    }

    @Override
    public Page<UserPropsRewardsVO> page(Long daoId, UserInfo user, Page page) {
        return this.page(daoId, user, null, null, null, null, page);
    }

    @Override
    public Page<UserPropsRewardsVO> page(Date startTime, Date endTime, String phoneNumber, List<Long> propsIds, Page page) {
        Long userId = null;
        if (StringUtils.isNotBlank(phoneNumber)) {
            UserInfo userInfo = userInfoService.getByUserTel(phoneNumber);
            if (userInfo != null) {
                userId = userInfo.getId();
            }
        }
        Long daoId = null;
        // 执行分页查询
        Page<UserPropsRewardsVO> propsRewardsPage = mallUserPropsRewardsDetailDao.getUserPropsRewardsSummaryPage(page, startTime, endTime, userId, daoId, propsIds);


        List<MallUserPropsReleasedDetail> list = mallUserPropsReleasedDetailDao.getReleasedSummaryList(startTime, endTime, userId, daoId, propsIds);

        // 构建查询条件
        LambdaQueryWrapper<MallUserPropsRewards> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userId != null, MallUserPropsRewards::getUserId, userId)
                .eq(daoId != null, MallUserPropsRewards::getDaoId, daoId)
                .in(CollectionUtil.isNotEmpty(propsIds), MallUserPropsRewards::getPropsId, propsIds);
        List<MallUserPropsRewards> mallUserPropsRewardsList = mallUserPropsRewardsDao.list(wrapper);

        Map<String, Integer> mallUserPropsRewardsMap = mallUserPropsRewardsList.stream()
                .collect(Collectors.toMap(
                        rewards -> rewards.getDaoId() + "_" + rewards.getUserId() + "_" + rewards.getPropsId(),
                        rewards -> rewards.getCreditedNum() - rewards.getReleasedNum(),
                        (existing, replacement) -> existing
                ));

        Map<String, Integer> releasedNumMap = list.stream()
                .collect(Collectors.toMap(
                        detail -> detail.getDaoId() + "_" + detail.getUserId() + "_" + detail.getPropsId(),
                        MallUserPropsReleasedDetail::getReleasedNum,
                        (existing, replacement) -> existing
                ));

        List<UserPropsRewardsVO> convertedRecords = propsRewardsPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        propsRewardsPage.setRecords(convertedRecords);

        for (UserPropsRewardsVO vo : propsRewardsPage.getRecords()) {
            String key = vo.getDaoId() + "_" + vo.getUserId() + "_" + vo.getPropsId();
            if (releasedNumMap.containsKey(key)) {
                vo.setReleasedNum(releasedNumMap.get(key));
            }
            if (mallUserPropsRewardsMap.containsKey(key)) {
                vo.setPendingReleaseNum(mallUserPropsRewardsMap.get(key));
            }
        }
        return propsRewardsPage;
    }

    public Page<UserPropsRewardsVO> page(Long daoId, UserInfo user, Date startTime, Date endTime, String phoneNumber, List<Long> propsIds, Page page) {
        Long userId = null;
        if (user != null) {
            userId = user.getId();
        }
        if (StringUtils.isNotBlank(phoneNumber)) {
            UserInfo userInfo = userInfoService.getByUserTel(phoneNumber);
            if (userInfo != null) {
                userId = userInfo.getId();
            }
        }
        // 构建查询条件
        LambdaQueryWrapper<MallUserPropsRewards> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(startTime != null, MallUserPropsRewards::getCreateTime, startTime)
                .le(endTime != null, MallUserPropsRewards::getCreateTime, endTime)
                .eq(userId != null, MallUserPropsRewards::getUserId, userId)
                .eq(daoId != null, MallUserPropsRewards::getDaoId, daoId)
                .in(CollectionUtil.isNotEmpty(propsIds), MallUserPropsRewards::getPropsId, propsIds)
                .orderByDesc(MallUserPropsRewards::getCreateTime);

        // 执行分页查询
        Page<MallUserPropsRewards> propsRewardsPage = mallUserPropsRewardsDao.page(page, wrapper);

        // 转换为VO对象
        Page<UserPropsRewardsVO> voPage = new Page<>(propsRewardsPage.getCurrent(), propsRewardsPage.getSize(), propsRewardsPage.getTotal());
        voPage.setRecords(propsRewardsPage.getRecords().stream().map(this::convertToVO).collect(Collectors.toList()));

        return voPage;
    }

    @Override
    public UserPropsRewardsSummaryVO getSummary(Date startTime, Date endTime, String phoneNumber, List<Long> propsIds) {
        Long userId = null;
        if (StringUtils.isNotBlank(phoneNumber)) {
            UserInfo userInfo = userInfoService.getByUserTel(phoneNumber);
            if (userInfo != null) {
                userId = userInfo.getId();
            }
        }
        Long daoId = null;
        UserPropsRewardsVO userPropsRewardsVO = mallUserPropsRewardsDetailDao.getUserPropsRewardsSummary(startTime, endTime, userId, daoId, propsIds);

        MallUserPropsReleasedDetail mallUserPropsReleasedDetail = mallUserPropsReleasedDetailDao.getReleasedSummary(startTime, endTime, userId, daoId, propsIds);

        // 构建查询条件
        UserPropsRewardsSummaryVO userPropsRewardsSummaryVO = mallUserPropsRewardsDao.getSummary(startTime, endTime, userId, propsIds);

        UserPropsRewardsSummaryVO result = new UserPropsRewardsSummaryVO();
        if (userPropsRewardsVO != null) {
            result.setTotalPendingNum(userPropsRewardsVO.getPendingNum());
            result.setTotalPendingAmount(userPropsRewardsVO.getPendingConsumptionAmount());
            result.setTotalCreditedNum(userPropsRewardsVO.getCreditedNum());
            result.setTotalConsumedAmount(userPropsRewardsVO.getCreditedConsumptionAmount());
        }
        if (mallUserPropsReleasedDetail != null) {
            result.setTotalReleasedNum(mallUserPropsReleasedDetail.getReleasedNum());
        }
        if (userPropsRewardsSummaryVO != null) {
            result.setTotalPendingReleaseNum(userPropsRewardsSummaryVO.getTotalPendingReleaseNum());
        }
        return result;
    }

    @Override
    public List<MallUserPropsRewards> selectByLastMinId(Long lastMinId, Integer pageSize, Date startTime) {
        return mallUserPropsRewardsDao.selectByLastMinId(lastMinId, pageSize, startTime);
    }

    private UserPropsRewardsVO convertToVO(MallUserPropsRewards mallUserPropsRewards) {
        UserPropsRewardsVO vo = new UserPropsRewardsVO();
        BeanUtils.copyProperties(mallUserPropsRewards, vo);

        // 如果需要获取用户手机号
        UserInfo userInfo = userInfoService.getById(mallUserPropsRewards.getUserId());
        if (userInfo != null) {
            vo.setPhoneNumber(userInfo.getUserTel());
            vo.setNickName(userInfo.getNickName());
        }
        EquityProps equityProps = equityPropsService.getById(mallUserPropsRewards.getPropsId());
        if (equityProps != null) {
            vo.setPropName(equityProps.getFirstTitle());
            vo.setCreationContent(equityProps.getCreationContent());
        }
        vo.setPendingReleaseNum(mallUserPropsRewards.getCreditedNum() - mallUserPropsRewards.getReleasedNum());
        return vo;
    }

    private UserPropsRewardsVO convertToVO(UserPropsRewardsVO userPropsRewardsVO) {
        UserPropsRewardsVO vo = new UserPropsRewardsVO();
        BeanUtils.copyProperties(userPropsRewardsVO, vo);

        // 如果需要获取用户手机号
        UserInfo userInfo = userInfoService.getById(userPropsRewardsVO.getUserId());
        if (userInfo != null) {
            vo.setPhoneNumber(userInfo.getUserTel());
            vo.setNickName(userInfo.getNickName());
        }
        EquityProps equityProps = equityPropsService.getById(userPropsRewardsVO.getPropsId());
        if (equityProps != null) {
            vo.setPropName(equityProps.getFirstTitle());
            vo.setCreationContent(equityProps.getCreationContent());
        }
        return vo;
    }
}
